﻿using System;
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace Anderson.Editor
{
    public class PlguinExport
    {
        private const string RootAssetsPath = "Assets";
        private const string AssemblyPath = "Library/ScriptAssemblies";

        //TODO;
        //ScriptObject Asset save DefaultExport Paths
        //This script redad asset to get paths
        //[MenuItem("Assets/IService/Assembly Export Paths")]
        //public static void OnGetPaths()
        //{
        //    string path = Application.dataPath;
        //    string editorPath = string.Format("{0}/{1}", path, "Editor");

        //    Debug.Log(editorPath);
        //    if (!Directory.Exists(editorPath))
        //    {
        //        return;
        //    }

        //    string[] files = Directory.GetFiles(editorPath, "*.asset");
        //    foreach (string item in files)
        //    {
        //        Debug.Log(item);

        //        ScriptableObject so = new ScriptableObject();
        //        无法从已经存在的asset中创建对应的ScriptableObject
        //    }

        //}

        [MenuItem("Assets/Anderson/Plugin Asset Export/x86_64", true)]
        private static bool IsExportPluginAssetEnabled_x86_64()
        {
            return InnserIsExportPluginAssetEnabled();
        }
        [MenuItem("Assets/Anderson/Plugin Asset Export/x64", true)]
        private static bool IsExportPluginAssetEnabled_x64()
        {
            return InnserIsExportPluginAssetEnabled();
        }
        [MenuItem("Assets/Anderson/Plugin Asset Export/OSX", true)]
        private static bool IsExportPluginAssetEnabled_OSX()
        {
            return InnserIsExportPluginAssetEnabled();
        }

        [MenuItem("Assets/Anderson/Plugin Asset Export/x86_64")]
        public static void OnExportPluginAsset_x86_64()
        {
            ExportInner(true, false, "x86_64");
        }

        [MenuItem("Assets/Anderson/Plugin Asset Export/x64")]
        public static void OnExportPluginAsset_x64()
        {
            ExportInner(false, true, "x64");
        }

        [MenuItem("Assets/Anderson/Plugin Asset Export/OSX")]
        public static void OnExportPluginAsset_OSX()
        {
            ExportInner(false, true, "OSX");
        }

        [MenuItem("Assets/Anderson/Assembly Export", true)]
        public static bool IsAssemblyExportEnabled()
        {
            return InnserIsAssemblyExportEnabled();
        }

        [MenuItem("Assets/Anderson/Assembly Export")]
        public static void OnExportAssembly()
        {
            ExportInner(false, false, "");
        }

        [MenuItem("Assets/Anderson/Plugin Export", true)]
        public static bool IsPluginExportEnabled()
        {
            return InnserIsAssemblyExportEnabled();
        }

        [MenuItem("Assets/Anderson/Plugin Export")]
        public static void OnExportPlugin()
        {
            ExportInner(false, true, "");
        }

        private static void ExportInner(bool isPluginAsset, bool renameToBytes, string subPath)
        {
            //1. 选择了哪些内容
            //2. 过滤不是AssemblyDefinition的选择
            //3. 找到.dll存放路径
            //4. 找到相应文件
            //5. 弹出目录选择对话框，记住选择的目录
            //6. 保存文件
            //7. 显示日志（成功个数/总个数）

            //0
            string path = Application.dataPath;
            path = path.Replace(RootAssetsPath, "");
            path = path + AssemblyPath;
            if (!Directory.Exists(path))
            {
                Debug.Log("不存在的目录：" + path);
            }

            //0
            string bundlePath = string.Format("{0}/{1}", Application.dataPath, BuildAssetBundles.AssetBundlePath);

            IList<string> fileList = new List<string>();
            //1.
            //2.
            Type t = null;
            AssemblyDefinitionAsset adfa = null;
            AssemblyDefinitionEnity entity;
            foreach (object item in Selection.objects)
            {
                if (isPluginAsset)
                {
                    break;
                }

                t = item.GetType();
                //Debug.Log(t.Name);
                //Debug.Log(item);
                
                if (typeof(AssemblyDefinitionAsset).IsAssignableFrom(t))
                {
                    adfa = (AssemblyDefinitionAsset)item;
                    entity = JsonUtility.FromJson<AssemblyDefinitionEnity>(adfa.text);

                    fileList.Add(entity.name);                    
                }
            }

            if (isPluginAsset)
            {
                string[] aab = AssetDatabase.GetAllAssetBundleNames();
                foreach (string item in aab)
                {
                    fileList.Add(item);
                    fileList.Add(item + ".manifest");
                }
            }

            //3.
            string assemblyPath = path;

            //4.
            string fileSource = "", fileDest = "";
            IList<string> exists = new List<string>();
            foreach (string item in fileList)
            {
                if (!isPluginAsset)
                {
                    fileSource = string.Format("{0}/{1}.dll", assemblyPath, item);
                }
                else
                {
                    fileSource = string.Format("{0}/{1}/{2}", bundlePath, subPath, item);
                }
                
                if (File.Exists(fileSource))
                {                    
                    exists.Add(item);
                    Debug.Log(fileSource);
                }
            }

            //5.        
            string sub = "Assembly";
            string defaultPath = "D:/Temp/Anderson/Assembly";

            if (!isPluginAsset && renameToBytes)
            {
                sub = "Plugin";
                defaultPath = "D:/Temp/Anderson/Plugins";
            }

            if (isPluginAsset)
            {
                sub = "Plugin Asset";
                defaultPath = "D:/Temp/Anderson/PluginAssets";
            }
            if (!Directory.Exists(defaultPath))
            {
                defaultPath = "";
            }

            string exportPath = EditorUtility.SaveFolderPanel(string.Format("Save {0} to Folder", sub), defaultPath, "");
            if (path.Length != 0)
            {
                foreach (string item in exists)
                {                    
                    if (!isPluginAsset)
                    {
                        fileSource = string.Format("{0}/{1}.dll", assemblyPath, item);
                        if (renameToBytes)
                        {
                            fileDest = string.Format("{0}/{1}.bytes", exportPath, item);
                        }
                        else
                        {
                            fileDest = string.Format("{0}/{1}.dll", exportPath, item);
                        }
                    }
                    else
                    {
                        fileSource = string.Format("{0}/{1}/{2}", bundlePath, subPath, item);
                        fileDest = string.Format("{0}/{1}", exportPath, item);
                    }

                    Debug.LogFormat("copy {0} to {1}", fileSource, fileDest);

                    File.Copy(fileSource, fileDest, true);
                }
            }
        }//func

        private static bool InnserIsAssemblyExportEnabled()
        {
            Type t;
            bool rightType = true;
            foreach (object item in Selection.objects)
            {
                t = item.GetType();

                if (!typeof(AssemblyDefinitionAsset).IsAssignableFrom(t))
                {
                    rightType = false;
                    break;
                }
            }

            return rightType;
        }

        private static bool InnserIsExportPluginAssetEnabled()
        {
            if (null != Selection.objects && Selection.objects.Length > 0)
            {
                return false;
            }

            return true;
        }

    }//class
}//namespace